﻿namespace E6BTest
{
    using Microsoft.VisualStudio.TestTools.UnitTesting;

    /// <summary>
    /// Conducts the Wind Correction Angle tests for the E6B.
    /// </summary>
    [TestClass]
    public class E6BWindCorrectionAngleTests : E6BTests
    {
        /// <summary>
        /// Specifies the acceptable variation between the test value and the
        /// actual return value.  A tolerance of 0.5 provides a 1 degree 
        /// margin of error around the expected value.
        /// </summary>
        private const double TOLERANCE = 0.5;

        /// <summary>
        /// Configures the test suite's E6B with the speeds and angles used for
        /// each test.
        /// </summary>
        /// <param name="context">The test context.</param>
        [ClassInitialize()]
        public static new void SuiteSetup(TestContext context)
        {
            E6BTests.SuiteSetup(context);
        }

        /// <summary>
        /// Cleans up any resources used by the E6B.
        /// </summary>
        [ClassCleanup()]
        public static new void SuiteCleanup()
        {
            E6BTests.SuiteCleanup();
        }

        /// <summary>
        /// <para>
        /// Verifies the E6B properly calculates the Wind Correction Angle (WCA).
        /// This calculation indicates the heading the aircraft must fly in order
        /// to maintain a desired track along the ground, compensating for wind
        /// direction and velocity.
        /// </para>
        /// <para>
        /// Formula: arcsin(( wind speed * sin(wind direction - desired course)) / true airspeed)
        /// </para>
        /// </summary>
        [TestMethod]
        public void WindCorrectionAngleTest1()
        {
            WindSpeed = 52;
            TrueAirspeed = 121;
            WindDirection = 190;
            Course = 173;
            ConfigureE6B();

            double expected = 7;    // based on hand calculations
            double actual = Computer.WindCorrectionAngle();
            Assert.AreEqual(expected, actual, TOLERANCE);
        }

        /// <summary>
        /// <para>
        /// Verifies the E6B properly calculates the Wind Correction Angle (WCA)
        /// using a value that is outside the normal range of 0 to 359 degrees.
        /// Allowable variance between expected and actual is 0.1 degrees.
        /// </para>
        /// <para>
        /// Formula: arcsin(( wind speed * sin(wind direction - desired course)) / true airspeed)
        /// </para>
        /// </summary>
        [TestMethod]
        public void WindCorrectionAngleTest2()
        {
            WindSpeed = 52;
            TrueAirspeed = 121;
            WindDirection = 190;
            Course = 533;
            ConfigureE6B();

            double expected = 7;    // based on hand calculationss
            double actual = Computer.WindCorrectionAngle();
            Assert.AreEqual(expected, actual, TOLERANCE);
        }

        /// <summary>
        /// Tests the WCA with a direct crosswind.
        /// </summary>
        [TestMethod]
        public void WindCorrectionAngleTest3()
        {
            WindDirection = 90;
            WindSpeed = 50;
            TrueAirspeed = 121;
            Course = 180;
            ConfigureE6B();

            double expected = -24;    // based on hand calculationss
            double actual = Computer.WindCorrectionAngle();
            Assert.AreEqual(expected, actual, TOLERANCE);
        }

        /// <summary>
        /// Tests the WCA with a direct tailwind.
        /// </summary>
        [TestMethod]
        public void WindCorrectionAngleTest4()
        {
            WindDirection = 0;
            WindSpeed = 50;
            TrueAirspeed = 121;
            Course = 180;
            ConfigureE6B();

            double expected = 0;    // based on hand calculationss
            double actual = Computer.WindCorrectionAngle();
            Assert.AreEqual(expected, actual, TOLERANCE);
        }

        /// <summary>
        /// Tests the WCA with a direct headwind.
        /// </summary>
        [TestMethod]
        public void WindCorrectionAngleTest5()
        {
            WindDirection = 180;
            WindSpeed = 50;
            TrueAirspeed = 121;
            Course = 180;
            ConfigureE6B();

            double expected = 0;    // based on hand calculationss
            double actual = Computer.WindCorrectionAngle();
            Assert.AreEqual(expected, actual, TOLERANCE);
        }
    }
}
